using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using SBS_Map_Editor.MapClasses;
//using SBS_Map_Editor.Manip;
//using SBS_Map_Editor.PBuffer;
using Mindshifter;

namespace SBS_Map_Editor
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        #region Variables
        #region Class Objects and Enumerators
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont spriteFont;
        Text text;
        #endregion

        #region Manipulator/Camera/Picker
        private Manipulator mManipulator;
        private Dictionary<uint, ModelNode> mModelNodes;

        private QuaternionCamera mCamera;

        private PickBuffer mPickBuffer;

        private bool mShowHelp;
        #endregion

        #region Map
        Texture2D nullTex;
        int curLedge = 0;
        #endregion

        #region Models
        Model[] mapModels;
        #endregion

        #region Input
        Texture2D iconsTex;
        int mosX, mosY;
        int PMosX, PMosY;
        int mouseDragSeg = -1;
        public static int curLayer = 1;
        bool mouseClick;
        //bool midMouseDown;
        bool mouseDown;
        Vector2 scroll = new Vector2(12f, 28f);
        #endregion

        #region Properties
        public static Map map { get; set; }
        public static DrawingMode DrawMode { get; set; }
        public static EditingMode EditMode { get; set; }
        public static Model MapModels { get; set; }
        #endregion
        #endregion

        #region Constructor
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            Components.Add(new Components.Editor(this));

            mPickBuffer = new PickBuffer(graphics);

            mCamera = new QuaternionCamera();
            mCamera.Position = (Vector3.UnitZ * 100f) + (Vector3.UnitY * 10f);

            mManipulator = new Manipulator(graphics, mCamera);
            mManipulator.EnabledModes = TransformationMode.TranslationAxis;

            mModelNodes = new Dictionary<uint, ModelNode>();

            IsMouseVisible = true;

            mShowHelp = true;

            InitializeInput();
        }

        private void InitializeInput()
        {
            IInputManager input = InputManager.Initialize(this);

            input.ActionMap.Bind(Keys.Escape, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                Exit();
            });

            input.ActionMap.Bind(Keys.D1, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.TranslationAxis) == TransformationMode.TranslationAxis)
                    mManipulator.EnabledModes &= ~TransformationMode.TranslationAxis;
                else
                    mManipulator.EnabledModes |= TransformationMode.TranslationAxis;
            });

            input.ActionMap.Bind(Keys.D2, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.TranslationPlane) == TransformationMode.TranslationPlane)
                    mManipulator.EnabledModes &= ~TransformationMode.TranslationPlane;
                else
                    mManipulator.EnabledModes |= TransformationMode.TranslationPlane;
            });

            input.ActionMap.Bind(Keys.D3, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.Rotation) == TransformationMode.Rotation)
                    mManipulator.EnabledModes &= ~TransformationMode.Rotation;
                else
                    mManipulator.EnabledModes |= TransformationMode.Rotation;
            });

            input.ActionMap.Bind(Keys.D4, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.ScaleAxis) == TransformationMode.ScaleAxis)
                    mManipulator.EnabledModes &= ~TransformationMode.ScaleAxis;
                else
                    mManipulator.EnabledModes |= TransformationMode.ScaleAxis;
            });

            input.ActionMap.Bind(Keys.D5, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.ScalePlane) == TransformationMode.ScalePlane)
                    mManipulator.EnabledModes &= ~TransformationMode.ScalePlane;
                else
                    mManipulator.EnabledModes |= TransformationMode.ScalePlane;
            });

            input.ActionMap.Bind(Keys.D6, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.EnabledModes & TransformationMode.ScaleUniform) == TransformationMode.ScaleUniform)
                    mManipulator.EnabledModes &= ~TransformationMode.ScaleUniform;
                else
                    mManipulator.EnabledModes |= TransformationMode.ScaleUniform;
            });

            input.ActionMap.Bind(Keys.D7, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                mManipulator.VectorSpace = VectorSpace.World;
            });

            input.ActionMap.Bind(Keys.D8, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                mManipulator.VectorSpace = VectorSpace.Local;
            });

            input.ActionMap.Bind(Keys.D9, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if ((mManipulator.Settings.Translation.AxisDrawMode & AxisDirections.Negative) == AxisDirections.Negative)
                    mManipulator.Settings.Translation.AxisDrawMode &= ~AxisDirections.Negative;
                else
                    mManipulator.Settings.Translation.AxisDrawMode |= AxisDirections.Negative;

                if ((mManipulator.Settings.Scale.AxisDrawMode & AxisDirections.Negative) == AxisDirections.Negative)
                    mManipulator.Settings.Scale.AxisDrawMode &= ~AxisDirections.Negative;
                else
                    mManipulator.Settings.Scale.AxisDrawMode |= AxisDirections.Negative;
            });

            input.ActionMap.Bind(Keys.OemQuestion, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                mShowHelp = !mShowHelp;
            });

            input.ActionMap.Bind(Keys.Z, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if (input[Keys.LeftControl])
                    mManipulator.Undo();
            });

            input.ActionMap.Bind(Keys.Y, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if (input[Keys.LeftControl])
                    mManipulator.Redo();
            });

            //input.ActionMap.Bind(Keys.W, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateZ(-mCameraSpeed * elapsed, TransformSpace.CameraSpace);
            //});

            //input.ActionMap.Bind(Keys.S, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateZ(mCameraSpeed * elapsed, TransformSpace.CameraSpace);
            //});

            //input.ActionMap.Bind(Keys.A, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateX(-mCameraSpeed * elapsed, TransformSpace.CameraSpace);
            //});

            //input.ActionMap.Bind(Keys.D, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateX(mCameraSpeed * elapsed, TransformSpace.CameraSpace);
            //});

            //input.ActionMap.Bind(Keys.Q, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateY(-mCameraSpeed * elapsed, TransformSpace.WorldSpace);
            //});

            //input.ActionMap.Bind(Keys.E, DiscreteInputEventType.Repeat, delegate(GameTime time)
            //{
            //    float elapsed = (float)time.ElapsedGameTime.TotalSeconds;
            //    mCamera.TranslateY(mCameraSpeed * elapsed, TransformSpace.WorldSpace);
            //});

            input.ActionMap.Bind(MouseButtons.Left, DiscreteInputEventType.Down, delegate(GameTime time)
            {
                if (mManipulator.Focused)
                    return;

                int mx = input.X;
                int my = input.Y;

                uint pick_id = mPickBuffer.Pick(mx, my);
                if (mModelNodes.ContainsKey(pick_id))
                    mManipulator.Transform = mModelNodes[pick_id];
                else
                    mManipulator.Transform = null;
            });
        }
        #endregion

        #region XNA Functions
        #region Initialize
        protected override void Initialize()
        {
            map = new Map();
            mapModels = new Model[10];

            base.Initialize();
        }
        #endregion

        #region Content
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            spriteFont = Content.Load<SpriteFont>(@"Font\Arial");

            text = new Text(spriteBatch, spriteFont);

            nullTex = Content.Load<Texture2D>(@"Textures\1x1");
            iconsTex = Content.Load<Texture2D>(@"Textures\icons");

            MainForm.LoadModel(Content, mapModels);
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        #endregion

        #region Update
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            mCamera.Update(elapsed);
            mManipulator.Update();

            #region Mouse
            MouseState mState = Mouse.GetState();
            mosX = mState.X;
            mosY = mState.Y;
            bool PMouseDown = mouseDown;
            if (mState.LeftButton == ButtonState.Pressed)
            {
                if (!mouseDown && GetCanEdit())
                {
                    if (DrawMode == DrawingMode.SegmentSelection)
                    {
                        int f = map.GetHoveredSegments(mosX, mosY, curLayer, scroll);

                        if (f != -1)
                            mouseDragSeg = f;
                    }
                    else if (DrawMode == DrawingMode.Ledge)
                    {
                        if (map.Ledges[curLedge] == null)
                            map.Ledges[curLedge] = new Ledge();

                        if (map.Ledges[curLedge].totalNodes < 15)
                        {
                            map.Ledges[curLedge].Nodes[map.Ledges[curLedge].totalNodes] =
                                new Vector2(mosX, mosY) + scroll / 2.0f;

                            map.Ledges[curLedge].totalNodes++;
                        }
                    }
                    //else if (drawType == DrawingMode.Script)
                    //{
                    //    if (selScript > -1)
                    //    {
                    //        if (mosX < 400)
                    //            map.scripts[selScript] += (" " +
                    //                ((int)((float)mosX + scroll.X / 2f)).ToString() + " " +
                    //                ((int)((float)mosY + scroll.Y / 2f)).ToString());
                    //    }
                    //}
                    else if (DrawMode == DrawingMode.CollisionMap)
                    {
                        int x = (mosX + (int)(scroll.X / 2)) / 32;
                        int y = (mosY + (int)(scroll.Y / 2)) / 32;
                        if (x >= 0 && y >= 0 && x < 20 && y < 20)
                        {
                            if (mState.LeftButton == ButtonState.Pressed)
                                map.Grid[x, y] = 1;
                            else if (mState.RightButton == ButtonState.Pressed)
                                map.Grid[x, y] = 0;
                        }
                    }
                }
                mouseDown = true;
            }
            else
                mouseDown = false;

            if (PMouseDown && !mouseDown) mouseClick = true;

            if (mouseDragSeg > -1)
            {
                if (!mouseDown)
                    mouseDragSeg = -1;
                else
                {
                    Vector2 loc = map.Segments[curLayer, mouseDragSeg].location;
                    loc.X += (mosX - PMosX);
                    loc.Y += (mosY - PMosY);
                    map.Segments[curLayer, mouseDragSeg].location = loc;
                }
            }

            //midMouseDown = (mState.MiddleButton == ButtonState.Pressed);

            //if (midMouseDown)
            //{
            //    scroll.X -= (mosX - PMosX) * 2.0f;
            //    scroll.Y -= (mosY - PMosY) * 2.0f;
            //}
            PMosX = mosX;
            PMosY = mosY;
            #endregion

            mPickBuffer.PushMatrix(MatrixMode.View, mCamera.ViewMatrix);
            mPickBuffer.PushMatrix(MatrixMode.Projection, mCamera.ProjectionMatrix);

            mPickBuffer.Render();

            base.Update(gameTime);
        }
        #endregion

        #region Draw
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            //DrawGrid();
            DrawLedges();

            //spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            //Color oColor = new Color(new Vector4(1.0f, 1.0f, 1.0f, 0.3f));
            //spriteBatch.Draw(nullTex, new Rectangle(100, 50, 400, 1), oColor);
            //spriteBatch.Draw(nullTex, new Rectangle(100, 50, 1, 500), oColor);
            //spriteBatch.Draw(nullTex, new Rectangle(500, 50, 1, 500), oColor);
            //spriteBatch.Draw(nullTex, new Rectangle(100, 550, 400, 1), oColor);

            //spriteBatch.Draw(nullTex, new Rectangle(100, 300, 400, 1), oColor);

            //spriteBatch.End();

            //foreach (ModelNode node in mModelNodes.Values)
            //{
            //    node.Draw(mCamera);
            //}

            mManipulator.Draw();

            #region Overlay
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
                SpriteSortMode.Immediate, SaveStateMode.SaveState);

            Color title_color = Color.White;
            Color unsel_color = Color.Yellow;
            Color sel_color = Color.Red;

            int ypos = 1;
            float yinc = 15f;

            spriteBatch.DrawString(spriteFont, "Toggle Manip Modes:", new Vector2(10f, ypos++ * yinc), title_color);
            spriteBatch.DrawString(spriteFont, "-------------------", new Vector2(10f, ypos++ * yinc), title_color);

            spriteBatch.DrawString(spriteFont, "1 - Translate Axis", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.TranslationAxis) == TransformationMode.TranslationAxis)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "2 - Translate Plane", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.TranslationPlane) == TransformationMode.TranslationPlane)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "3 - Rotate", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.Rotation) == TransformationMode.Rotation)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "4 - Scale Axis", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.ScaleAxis) == TransformationMode.ScaleAxis)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "5 - Scale Plane", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.ScalePlane) == TransformationMode.ScalePlane)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "6 - Scale Uniform", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.EnabledModes & TransformationMode.ScaleUniform) == TransformationMode.ScaleUniform)
                    ? (sel_color)
                    : (unsel_color));

            ypos++;

            spriteBatch.DrawString(spriteFont, "Vector Space:", new Vector2(10f, ypos++ * yinc), title_color);
            spriteBatch.DrawString(spriteFont, "-------------", new Vector2(10f, ypos++ * yinc), title_color);

            spriteBatch.DrawString(spriteFont, "7 - World Space", new Vector2(10f, ypos++ * yinc),
                (mManipulator.VectorSpace == VectorSpace.World)
                    ? (sel_color)
                    : (unsel_color));

            spriteBatch.DrawString(spriteFont, "8 - Local Space", new Vector2(10f, ypos++ * yinc),
                (mManipulator.VectorSpace == VectorSpace.Local)
                    ? (sel_color)
                    : (unsel_color));

            ypos++;

            spriteBatch.DrawString(spriteFont, "9 - Toggle Negative Axes", new Vector2(10f, ypos++ * yinc),
                ((mManipulator.Settings.Translation.AxisDrawMode & AxisDirections.Negative) == AxisDirections.Negative)
                    ? (sel_color)
                    : (unsel_color));

            ypos++;

            spriteBatch.DrawString(spriteFont, "? - Show/Hide All Keys", new Vector2(10f, ypos++ * yinc),
                (mShowHelp)
                    ? (sel_color)
                    : (unsel_color));
            #endregion

            #region Help
            // draw help
            if (mShowHelp)
            {
                spriteBatch.DrawString(spriteFont, "W - Cam Forward", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "S - Cam Back", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "A - Cam Left", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "D - Cam Right", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "Q - Cam Down", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "E - Cam Up", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "Right Mouse - Cam Pitch/Yaw", new Vector2(10f, ypos++ * yinc), Color.White);
                spriteBatch.DrawString(spriteFont, "Left Mouse - Interact", new Vector2(10f, ypos++ * yinc), Color.White);

                spriteBatch.DrawString(spriteFont, "Ctrl Z - Undo", new Vector2(10f, ypos++ * yinc),
                (mManipulator.UndoStackSize != 0)
                    ? (unsel_color)         // undo enabled
                    : (Color.DarkGray));    // undo disabled

                spriteBatch.DrawString(spriteFont, "Ctrl Y - Redo", new Vector2(10f, ypos++ * yinc),
                (mManipulator.RedoStackSize != 0)
                    ? (unsel_color)         // redo enabled
                    : (Color.DarkGray));    // redo disabled
            }

            spriteBatch.End();
            #endregion

            switch (DrawMode)
            {
                case DrawingMode.SegmentSelection:
                    //DrawMapSegments();
                    break;
                case DrawingMode.Ledge:
                    DrawLedgePallete();
                    break;
                case DrawingMode.Script:
                    //DrawScript();
                    break;
            }

            //Vector2 v = new Vector2((float)mosX, (float)mosY) + scroll / 2.0f;
            //v *= 2f;
            Vector2 v = new Vector2((float)mosX, (float)mosY);
            text.Color = Color.White;
            text.DrawText(5, 580, ((int)v.X).ToString() + ", " +
                ((int)v.Y).ToString());

            base.Draw(gameTime);
        }
        #endregion
        #endregion

        #region Helper Functions
        #region checking functions (bool)
        private bool GetCanEdit()
        {
            if (mosX > 100 && mosX < 500 && mosY > 100 && mosY < 550)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region Draw
        private void DrawGrid()
        {
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

            for (int y = 0; y < 20; y++)
            {
                for (int x = 0; x < 20; x++)
                {
                    Rectangle dRect = new Rectangle(
                        x * 32 - (int)(scroll.X / 2),
                        y * 32 - (int)(scroll.Y / 2),
                        32, 32);

                    if (x < 19)
                        spriteBatch.Draw(nullTex, new Rectangle(
                            dRect.X, dRect.Y, 32, 1), new Color(255, 0, 0, 100));

                    if (y < 19)
                        spriteBatch.Draw(nullTex, new Rectangle(
                            dRect.X, dRect.Y, 1, 32), new Color(255, 0, 0, 100));

                    if (x < 19 && y < 19)
                    {
                        if (map.Grid[x, y] == 1)
                        {
                            spriteBatch.Draw(nullTex, dRect, new Color(255, 0, 0, 100));
                        }
                    }
                }
            }

            Color oColor = new Color(255, 255, 255, 100);
            spriteBatch.Draw(nullTex, new Rectangle(100, 50, 400, 1), oColor);
            spriteBatch.Draw(nullTex, new Rectangle(100, 50, 1, 500), oColor);
            spriteBatch.Draw(nullTex, new Rectangle(500, 50, 1, 500), oColor);
            spriteBatch.Draw(nullTex, new Rectangle(100, 550, 400, 1), oColor);

            spriteBatch.End();
        }

        private void DrawingLedge()
        {
            for (int i = 0; i < 16; i++)
            {
                if (map.Ledges[i] == null)
                    continue;

                int y = 50 + i * 20;
                if (curLedge == i)
                {
                    text.Color = Color.Lime;
                    text.DrawText(520, y, "ledge " + i.ToString());
                }
                else
                {
                    if (text.DrawClickText(520, y, "ledge " + i.ToString(),
                        mosX, mosY, mouseClick))
                        curLedge = i;
                }
                text.Color = Color.White;
                text.DrawText(620, y, "n" + map.Ledges[i].totalNodes.ToString());

                if (text.DrawClickText(680, y, "f" + map.Ledges[i].flags.ToString(), mosX, mosY, mouseClick))
                    map.Ledges[i].flags = (map.Ledges[i].flags + 1) % 2;
            }
        }

        private void DrawLedges()
        {
            Rectangle rect = new Rectangle();
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            Color tColor = new Color();

            rect.X = 32;
            rect.Y = 0;
            rect.Width = 32;
            rect.Height = 32;

            for (int i = 0; i < 16; i++)
            {
                if (map.Ledges[i] != null && map.Ledges[i].totalNodes > 0)
                {
                    for (int n = 0; n < map.Ledges[i].totalNodes; n++)
                    {
                        Vector2 tVec;
                        tVec = map.Ledges[i].Nodes[n];
                        tVec -= scroll / 2.0f;
                        tVec.X -= 5.0f;
                        if (curLedge == i)
                            tColor = Color.Yellow;
                        else
                            tColor = Color.White;
                        spriteBatch.Draw(iconsTex, tVec, rect, tColor, 0.0f, Vector2.Zero,
                            0.35f, SpriteEffects.None, 0.0f);

                        if (n < map.Ledges[i].totalNodes - 1)
                        {
                            Vector2 nVec;
                            nVec = map.Ledges[i].Nodes[n + 1];
                            nVec -= scroll / 2.0f;
                            nVec.X -= 4.0f;
                            for (int x = 0; x < 20; x++)
                            {
                                Vector2 iVec = (nVec - tVec) * ((float)x / 20.0f) + tVec;

                                Color nColor = new Color(255, 255, 255, 75);
                                if (map.Ledges[i].flags == 1)
                                    nColor = new Color(255, 255, 255, 75);
                                spriteBatch.Draw(iconsTex, iVec, rect, nColor, 0.0f, Vector2.Zero,
                                    0.25f, SpriteEffects.None, 0.0f);
                            }
                        }
                    }
                }
            }

            spriteBatch.End();
        }

        private void DrawLedgePallete()
        {
            for (int i = 0; i < 16; i++)
            {
                if (map.Ledges[i] == null)
                    continue;

                int y = 50 + i * 20;
                if (curLedge == i)
                {
                    text.Color = Color.Lime;
                    text.DrawText(520, y, "ledge " + i.ToString());
                }
                else
                {
                    if (text.DrawClickText(520, y, "ledge " + i.ToString(), mosX, mosY, mouseClick))
                        curLedge = i;
                }
                text.Color = Color.White;
                text.DrawText(620, y, "n" + map.Ledges[i].totalNodes.ToString());

                if (text.DrawClickText(680, y, "f" + map.Ledges[i].flags.ToString(), mosX, mosY, mouseClick))
                    map.Ledges[i].flags = (map.Ledges[i].flags + 1) % 2;
            }
        }
        #endregion
        #endregion
    }
}